package com.project.bookstore.order.service.impl;

import com.project.bookstore.book.service.BookService;
import com.project.bookstore.cart.service.ICartService;
import com.project.bookstore.common.CommonResult;
import com.project.bookstore.common.State;
import com.project.bookstore.exception.ServiceException;
import com.project.bookstore.exception.ServiceInternalException;
import com.project.bookstore.order.domain.Order;
import com.project.bookstore.order.mapper.OrderMapper;
import com.project.bookstore.order.pojo.*;
import com.project.bookstore.order.service.OrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private BookService bookService;

    @Autowired
    private ICartService cartService;

    //订单多条件查询
    @Override
    public CommonResult<List<OrderDetailVO>> orderMultiCondition(Long userId, OrderMultiConditionDTO conditionDTO) {
        if (conditionDTO.getStartDate() != null)
            badDateConditionHandler(conditionDTO);
        List<OrderDetailDO> orderDetailDOS = orderMapper.multiCondition(userId, conditionDTO);
        log.debug("orderDetailDOS:【{}】",orderDetailDOS);
        List<OrderDetailVO> orderDetailVOS = orderDetailDOToVO(orderDetailDOS);
        log.debug("orderDetailVOS:【{}】",orderDetailVOS);
        return CommonResult.ok(orderDetailVOS);
    }

    //不好的日期条件处理
    private void badDateConditionHandler(OrderMultiConditionDTO conditionDTO) {
        LocalDate startDate = conditionDTO.getStartDate();
        LocalDate endDate = conditionDTO.getEndDate();
        if (startDate.isAfter(endDate)) {
            log.debug("提交的开始日期【{}】在结束日期【{}】之后,进行调换", startDate, endDate);
            conditionDTO.setEndDate(startDate);
            conditionDTO.setStartDate(endDate);
        }
        log.debug("调换后 start:{},end:{}", startDate, endDate);
    }

    //订单列表
    @Override
    public CommonResult<List<OrderDetailVO>> orderList(Long userId) {
        List<OrderDetailDO> orderList = orderMapper.multiCondition(userId, new OrderMultiConditionDTO());
        if (orderList == null){
            log.warn("订单列表为空");
            throw new ServiceInternalException();
        }
        log.debug("订单列表位:【{}】", orderList);
        List<OrderDetailVO> orderDetailVOS = orderDetailDOToVO(orderList);
        return CommonResult.ok(orderDetailVOS);
    }

    @Override
    public CommonResult<Void> createOrder(OrderCreateVO orderCreateVO) {
        // 查看所选书籍列表是否都有库存
        Map<Long, Integer> bookPCSMap = orderCreateVO.getBooks().stream().collect(Collectors.toMap(
                BookInCreateOrderVO::getId,
                BookInCreateOrderVO::getCount,
                (a, b) -> a > b ? b : a
        ));
        if (!bookService.hasPCS(bookPCSMap)) {
            log.warn("生成订单时库存不足");
            throw new ServiceException(State.NO_STOCK, "订单包含书籍库存不足");
        }
        // 减库存、改销量
        bookService.updateSaleCountPCS(bookPCSMap);
        //删购物车
        Long[] cartIds = orderCreateVO.getBooks().stream().map(BookInCreateOrderVO::getId).toArray(Long[]::new);
        if (cartService.multiDeleteByIds(cartIds)!=cartIds.length){
            log.debug("根据购物车ID数组【{}】批量删除购物车数据发生未知错误",cartIds);
            throw new ServiceInternalException();
        }
        Order commonOrder = new Order();
        commonOrder.setAddressId(orderCreateVO.getAddressId())
                .setUserId(orderCreateVO.getUserId())
                .setCreated(LocalDateTime.now())
                .setOrderNumber(UUID.randomUUID().toString())
                .setExpressOrder(UUID.randomUUID().toString())
                .setState(OrderState.TOBE_PAY.getState());
        // 生成订单，设置订单状态、总金额、生成发货单号和订单号UUID、创建时间
        List<Order> orders = orderCreateVO.getBooks().stream().map(e -> {
            Order order = new Order();
            BeanUtils.copyProperties(commonOrder, order);   //共有属性赋值
            log.debug("赋值共有属性后为：【{}】", order);
            //再次时候 BeanUtils.copy会覆盖已有属性为空，下面手动复制
            order.setBookPicture(e.getPicture());
            order.setBookId(e.getBookId());
            order.setAmount(e.getAmount());
            order.setBookName(e.getBookName());
            order.setRemarks(e.getRemarks());
            order.setCount(e.getCount());
            order.setPrice(e.getPrice());
            log.debug("赋值书籍属性后为：【{}】", order);
            return order;
        }).collect(Collectors.toList());
        int i = orderMapper.multiInsert(orders);
        if (i != orders.size()) {
            log.warn("批量插入订单未知错误");
            throw new ServiceInternalException();
        }
        log.debug("创建订单完成返回ok");
        return CommonResult.ok();
    }

    //订单状态统计
    public CommonResult<HashMap<String, Integer>> countState(Long userId) {
        log.debug("开始统计用户【{}】订单", userId);
        List<CountStateEntity> countStateEntities = orderMapper.countState(userId);
        log.debug("数据库中订单统计为【{}】,准备整理为map", countStateEntities);
        HashMap<String, Integer> orderCount = new HashMap<>(6);
        for (CountStateEntity next : countStateEntities) {
            orderCount.put(next.getStateName(), next.getCount());
        }
        //用查询到的结果覆盖初始集合
        HashMap<String, Integer> initMap = CountStateEntity.getInitMap();
        initMap.putAll(orderCount);
        log.debug("统计订单状态结果:【{}】", initMap);
        return CommonResult.ok(initMap);
    }

    public List<OrderDetailVO> orderDetailDOToVO(List<OrderDetailDO> orderDO) {
        HashMap<String, OrderDetailVO> orderDetailVOHashMap = new HashMap<>();
        for (OrderDetailDO e :orderDO) {
            OrderDetailVO orderDetailVO = new OrderDetailVO();
            BookInCreateOrderVO bookInCreateOrderVO = new BookInCreateOrderVO();
            //未保存的订单号
            if (!orderDetailVOHashMap.containsKey(e.getOrderNumber())) {
                //复制订单数据
                BeanUtils.copyProperties(e, orderDetailVO);
                String address = e.getProvince() + e.getCity() + e.getArea() + e.getDetailAdd();
                log.debug("orderDOToVO address:【{}】", address);
                //设置地址属性
                orderDetailVO.setAddress(address);
                //复制图书数据
                BeanUtils.copyProperties(e, bookInCreateOrderVO);
                if (orderDetailVO.getBooks()==null)
                    orderDetailVO.setBooks(new ArrayList<BookInCreateOrderVO>());
                bookInCreateOrderVO.setPicture(e.getBookPicture());
                orderDetailVO.getBooks().add(bookInCreateOrderVO);
                orderDetailVOHashMap.put(e.getOrderNumber(), orderDetailVO);
                continue;
            }
            //订单号已经存在了,复制书籍信息即可
            BeanUtils.copyProperties(e, bookInCreateOrderVO);
            bookInCreateOrderVO.setPicture(e.getBookPicture());
            orderDetailVOHashMap.get(e.getOrderNumber()).getBooks().add(bookInCreateOrderVO);
        }
        Collection<OrderDetailVO> values = orderDetailVOHashMap.values();
        return new ArrayList<>(values);
    }

}
